package com.masiyi.executor;

import com.masiyi.entity.Configuration;
import com.masiyi.entity.MappedStatement;
import com.masiyi.util.MyMybatisUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author masiyi
 * @Date 2023/11/10
 * @PackageName:com.masiyi.executor
 * @ClassName: SimpleExecutor
 * @Description: 执行器，把jdbc里面的代码拿过来
 * Connection conn = null;
 * Statement stmt = null;
 * ResultSet rs = null;
 * @Version 1.0
 */

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SimpleExecutor {

    private Connection conn = null;
    private Statement stmt = null;
    private ResultSet rs = null;


    @SneakyThrows
    public <E> List<E> query(Configuration configuration, MappedStatement mappedStatement, Object param) {
        // 获取数据库连接
        conn = configuration.getDataSource().getConnection();

        // 获取 SQL 语句
        String sql = mappedStatement.getSql();

        // 创建 PreparedStatement 对象，并将 SQL 语句中的占位符替换为实际的参数值
        PreparedStatement preparedStatement = conn.prepareStatement(MyMybatisUtil.replacePlaceholders(sql,param));

        // 执行查询操作，获取结果集
        rs = preparedStatement.executeQuery();

        // 处理返回结果集
        ArrayList<E> list = new ArrayList<>();
        // 遍历结果集的每一行
        while (rs.next()){
            // 获取结果集的元数据信息，包含字段名和字段值的信息
            ResultSetMetaData metaData = rs.getMetaData();

            // 获取结果类型
            String resultType = mappedStatement.getResultType();
            // 根据结果类型获取对应的类对象
            Class<?> resultTypeClass = Class.forName(resultType);
            // 创建结果对象的实例
            Object o = resultTypeClass.newInstance();

            // 遍历结果集的每一列
            for (int i = 1; i <= metaData.getColumnCount() ; i++) {
                // 获取字段名
                String columnName = metaData.getColumnName(i);
                // 获取字段的值
                Object value = rs.getObject(columnName);

                PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName, resultTypeClass);
                // 创建属性描述器，用于获取属性的读写方法
                Method writeMethod = propertyDescriptor.getWriteMethod();
                // 调用属性的写方法，将字段值设置到结果对象中
                writeMethod.invoke(o,value);
            }
            // 将结果对象添加到列表中
            list.add((E) o);
        }


        return list;
    }


    /**
     * 关闭资源
     */
    public void close() {
        // 关闭资源
        try {
            if (rs != null) {
                rs.close();
            }
            if (stmt != null) {
                stmt.close();
            }
            if (conn != null) {
                conn.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}


